/**
 * Design By: CEC GienTech Technology Co.,Ltd. All rights reserved.
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ccdc.cbpc.bigdata.common.util.security;

import com.ccdc.cbpc.bigdata.open.common.enums.RespCodeEnum;
import com.ccdc.cbpc.bigdata.open.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.security.MessageDigest;

/**
 * MD5加密工具。
 * @title com.pactera.dmc.common.util.security.Md5Util
 * @description Md5Util
 * @author <a href="dong.zhang8@pactera.com">zhangdong</a>
 * @date 2021/7/19
 * @since 1.0.0
 */
@Slf4j
public class Md5Util {
    /**默认编码*/
    private static final String DEFAULT_CHARSETNAME = "UTF-8";
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    private Md5Util() {
        throw new IllegalStateException("Utility class");
      }

    public static String generalKeyWord(String... args) {
		return md5(ArrayUtils.toString(args, ","));
	}
    /**
     * 转换十六进制
     * @param b
     * @return
     */
    private static String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
            sb.append(HEX_DIGITS[b[i] & 0x0f]);
        }
        return sb.toString();
    }
    /**
     * MD5加密
     *
     * @param str
     * @return
     */
    public static final String md5(String str) throws BusinessException {
        return md5(str,DEFAULT_CHARSETNAME);
    }
    /**
     * MD5加密
     *
     * @param str 加密原串
     * @param charsetName 编码
     * @return
     */
    public static final String md5(String str,String charsetName) throws BusinessException {
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("MD5");
            digest.update(str.getBytes(charsetName));
            byte[] messageDigest = digest.digest();
            return toHexString(messageDigest);
        } catch (Exception e) {
            log.error("md5加密失败",e);
            throw new BusinessException(RespCodeEnum.SERVER_ERROR,"加密服务异常");
        }
    }
    /**
     * 32位转16位
     */
    public static final String md5_32_16(String src) throws BusinessException {
        return src.substring(8,24);
    }
    /**
     * 16位转32位注意不是还原成32位
     */
    public static final String md5_16_32(String src) throws BusinessException {
        byte[] bytes = src.getBytes();
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            buffer.append(String.format("%02X", bytes[i]));
        }
        return buffer.toString();
    }
    /**
     * MD5加密 16位
     * @param str
     * @param charsetName
     * @return
     * @throws BusinessException
     */
    public static final String md5_16(String str,String charsetName) throws BusinessException {
        return md5_32_16(md5(str,charsetName));
    }
    /**
     *     MD5加密 16位
     */
    public static final String md516(String str) throws BusinessException {
        return md5_16(str,DEFAULT_CHARSETNAME);
    }

    public static String encodeMoreDataByMD5(String[] fieldsData) {
        return encodeMoreDataByMD5('_',fieldsData);
    }
    /*
    ***
    * 指定数据分割符，对多个数据合并后，生成摘要
	 * @param splitStr
	 * @param datas
	 * @return
    */
    public static String encodeMoreDataByMD5(char splitStr,String... datas){
        if(datas!=null){
            StringBuffer sb = new StringBuffer();
            for (String string : datas) {
                if(string!=null){
                    sb.append(string);
                    sb.append(splitStr);
                }
            }
            return md5(sb.toString());
        }
        return null;
    }
}
